package com.feri.tiantian.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feri.tiantian.conest.LogType;
import com.feri.tiantian.config.RedisConfig;
import com.feri.tiantian.dao.UserDao;
import com.feri.tiantian.dao.UserLogDao;
import com.feri.tiantian.entity.User;
import com.feri.tiantian.entity.UserLog;
import com.feri.tiantian.service.intf.UserService;
import com.feri.tiantian.utils.JedisUtils;
import com.feri.tiantian.utils.PassUtils;
import com.feri.tiantian.utils.StringUtils;
import com.feri.tiantian.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;


@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserLogDao userLogDao;
    @Value("${user.passkey}")
    private String key;
    @Override
    @Transactional
    public R login(String phone, int code,String ip) {
        //唯一登陆  如果是第一次 自动注册
        //1 手机号码和验证码不为空
        if (StringUtils.isNoyEmpty(phone) && code>0){
            //2 查询是否存在短信验证码
            if (JedisUtils.esists(RedisConfig.SMS_CODE_LOGIN + phone)){
                //3  存在 判断输入的验证码与发送的验证码是否一致
                if(code == Integer.parseInt(JedisUtils.getStr(RedisConfig.SMS_CODE_LOGIN + phone))){
                    //4 验证当前手机号 是否已经注册
                    QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
                    User user = userDao.selectOne(userQueryWrapper.eq("phone", phone));
                    if (user==null){
                        //5 当前登陆的手机号不存在需要自动注册  存在则不用管
                        user.setCtime(new Date());
                        user.setFlag(1);
                        user.setPhone(phone);
                        userDao.insert(user);
                        //6 记录日志
                        userLogDao.insert(new UserLog(user.getId(), LogType.注册.getValue(), "手机号验证码登陆，实现自动注册", ip, new Date()));
                    }

                    //7  校验当前手机号是否在线 唯一登陆
                    if (JedisUtils.esists(RedisConfig.LOGIN_PHONE+phone)){
                        //存在手机号 说明已经在线
                        // 8 生成挤掉信息（如果是app 需要使用第三方推送工具(极光、个推等）
                        //存储挤掉信息
                        JedisUtils.setStr(RedisConfig.LOGIN_LOSE,JedisUtils.getStr(RedisConfig.LOGIN_PHONE+phone));
                       //   清理原来的令牌
                        JedisUtils.del(RedisConfig.LOGIN_TOKEN+JedisUtils.getStr(RedisConfig.LOGIN_PHONE+phone));
                    }

                    // 9 生成令牌  AES算法 对手机号和时间戳加密保证生成的令牌不一样 - 密文就是令牌
                    String token = PassUtils.aesenc(key, phone+"_"+System.currentTimeMillis());

                    //10 redis存储令牌 有状态  有效期30分钟
                    JedisUtils.setStr(RedisConfig.LOGIN_TOKEN+token, JSON.toJSONString(user) +"",RedisConfig.LOGIN_TOKEN_TIME);
                    JedisUtils.setStr(RedisConfig.LOGIN_PHONE+phone,token,RedisConfig.LOGIN_TOKEN_TIME);
                    //11记录登陆日志
                    userLogDao.insert(new UserLog(user.getId(), LogType.登录.getValue(), "手机号验证码登陆", ip, new Date()));

                    //12 返回令牌
                    return R.ok(token);
                }
            }
        }
        return R.fail("网络故障！");
    }

    //通过令牌查询用户信息
    @Override
    public R query(String token) {
        if (StringUtils.isNoyEmpty(token)){
            //验证令牌是否有效
            if (JedisUtils.esists(RedisConfig.LOGIN_TOKEN+token)){
                //查询令牌对应的用户信息
                User user = JSON.parseObject(JedisUtils.getStr(RedisConfig.LOGIN_TOKEN + token), User.class);
                user.setPassword("");//密码脱敏 真实密码不返回到前端
                return R.ok(user);
            }
        }
        return R.fail("令牌无效");
    }


    //校验令牌是否有效
    @Override
    public R queryToken(String token) {
        if (StringUtils.isNoyEmpty(token)) {
            if (JedisUtils.check(RedisConfig.LOGIN_LOSE,token)){
                JedisUtils.delSet(RedisConfig.LOGIN_LOSE,token);
                return R.fail("账号已在别处登陆");
            }else {  //没被挤掉 需要验证令牌是否失效
                //令牌有效
                if (JedisUtils.esists(RedisConfig.LOGIN_TOKEN+token)){
                    return R.ok();
                }else {
                    return R.fail("令牌失效,请重新登陆！");
                }
            }
        }
        //  查询所有的被挤掉的令牌
        return R.fail("无效令牌");
    }

    @Override
    public R loginout(String token) {
        if(StringUtils.isNoyEmpty(token)){
            if (JedisUtils.esists(RedisConfig.LOGIN_TOKEN+token)){
                User user = JSON.parseObject(JedisUtils.getStr(RedisConfig.LOGIN_TOKEN + token), User.class);
                JedisUtils.del(RedisConfig.LOGIN_TOKEN+token,RedisConfig.LOGIN_PHONE+user.getPhone());

            }
        }
        return null;
    }

    @Override
    public R all() {
        return null;
    }
}
